<template>
  <movable-area class="drag-sort" :style="{height: currentListLength + 'px'}" id="drag">
    <movable-view
      v-for="(item, index) in currentList"
      :key="index"
      :x="2000"
      :y="item.y"
      direction="vertical"
      disabled
      damping="40"
      :animation="active !== index"
      class="drag-sort-item"
      :class="{'active': item.active}"
			style="height:55px"
    >
      <view class="module-item" :class="{ 'active': item.active }">
        <view class="handle"
          @touchstart.stop="touchstart($event, index)"
          @touchmove.stop="touchmove($event)"
          @touchend.stop="touchend($event)"
        >
          <u-icon name="list" color="#999" size="24"></u-icon>
        </view>
        <view class="content">{{ item[props.props.label] }}</view>
        <view class="action" @click.stop="updateActive(index)" >
          <template v-if="item.active">
            <u-icon name="minus-circle" color="#ff5722" size="24" ></u-icon>
          </template>
          <template v-else>
            <u-icon name="plus-circle" color="#5ac725" size="24" ></u-icon>
          </template>
        </view>
      </view>
    </movable-view>
    <!-- <movable-view
      class="touch"
      :x="2000"
      catchtouchstart
      catchtouchmove
      catchtouchend
    ></movable-view> -->
  </movable-area>
</template>

<script setup lang="ts">
// 声明uni全局变量，避免linter报错
declare const uni: any;
import { ref, computed, unref, toRaw, watch, getCurrentInstance } from 'vue'
	const props = defineProps({
	  list: {
	    type: Array,
			default: () => [] 
	  },
		props: {
			type: Object,
			default: () => {
				return {
					label: 'label',
					value: 'value'
				}
			}
		}
	});


	const emits = defineEmits(['change', 'update:active', 'update:list']);
	
	const height = ref(55) // 高度
	const gap = 30 // 增大间距
	const currentList = ref<any>([])
	const active = ref(-1) // 当前激活的item
	const itemIndex = ref(0) // 当前激活的item的原index
	const topY = ref(0) // 距离顶部的距离
	const deviationY = ref(0) // 偏移量
	const instance = getCurrentInstance()
	
	const currentListLength = computed(() => {
		return toRaw(currentList.value).length * unref(height) + (toRaw(currentList.value).length - 1) * gap
	})
  watch(
    () => props.list,
    (val) => {
      // console.log('props.list 变化：', val)
			onUpdateCurrentList()
    },
    { immediate: true, deep: true }
  )
	function onUpdateCurrentList () {
		let arr: any[] = []
		// console.log('props.list：',props.list);
		for (let i = 0; i < props.list.length; i++) {
			arr.push({
				...toRaw(props.list[i]) as any,
				index: i,
				y: i * (unref(height) + gap),
				animation: true
			})
		}
    currentList.value = arr
	}
	function touchstart(e, idx) {
		console.log('touchstart idx:', idx, typeof idx)
		// 设置当前激活项
		active.value = idx
		// 计算y轴点击位置
		let query = uni.createSelectorQuery().in(instance)
		query.select('#drag').boundingClientRect()
		query.exec((res: any) => {
			topY.value = res[0].top
			let touchY = e.touches[0].clientY - res[0].top
			// 计算点击位置在元素内的偏移量
			const itemY = idx * (unref(height) + gap)
			deviationY.value = touchY - itemY // 修正为相对于元素顶部的偏移
			itemIndex.value = idx
		})
	}
	function touchmove (e) {
		if (unref(active) < 0) return
		// 获取手指位置并减去初始点击位置在元素内的偏移量，以保证元素跟随手指
		let touchY = (e.touches[0].clientY - unref(topY)) - unref(deviationY)
		
		// 限制拖动范围，防止超出边界
		const minY = 0
		const maxY = (currentList.value.length - 1) * (unref(height) + gap)
		touchY = Math.max(minY, Math.min(touchY, maxY))
		
		// 计算新 index
		let newIndex = Math.round(touchY / (unref(height) + gap))
		newIndex = Math.max(0, Math.min(newIndex, currentList.value.length - 1))
		const oldIndex = currentList.value[unref(active)].index
		
		// 更新拖动元素位置
		currentList.value[unref(active)].y = touchY
		
		if (newIndex !== oldIndex) {
			// 重新排序 currentList
			const movedItem = currentList.value.splice(unref(active), 1)[0]
			currentList.value.splice(newIndex, 0, movedItem)
			// 重新设置所有项的 index 和 y
			currentList.value.forEach((item, i) => {
				item.index = i
				if (i !== newIndex) { // 只更新非当前拖动项的位置
					item.y = i * (unref(height) + gap)
				}
			})
			active.value = newIndex
		}
	}
	function touchend (e) {
		console.log('touchend',e)
		if (unref(active) < 0) return
		
		// 动画恢复正常位置
		const currentIndex = currentList.value[unref(active)].index
		currentList.value[unref(active)].animation = true
		currentList.value[unref(active)].y = currentIndex * (unref(height) + gap)
		
		// 发送change事件，如果位置有变化
		if (unref(itemIndex) !== currentIndex) {
			emits('change', {
				// 操作值
				data: (() => {
					let data = {
						...toRaw(currentList.value)[unref(active)]
					}
					delete data.index
					delete data.y
					delete data.animation
					return data
				})(),
				// 插队的位置前面的值
				frontData: (() => {
					for (const iterator of toRaw(currentList.value)) {
						if (currentIndex - 1 === iterator.index) {
							let data = {
								...iterator
							}
							delete data.index
							delete data.y
							delete data.animation
							return data
						}
					}
				})()
			})
		}
		
		// 拖动结束后，重置激活状态
		active.value = -1
		
		// 拖动结束后，刷新所有项的index和y，保证间距和顺序正确
		currentList.value.forEach((item, i) => {
			item.index = i
			item.y = i * (unref(height) + gap)
		})
		
		// 拖动结束后，emit新顺序，保证v-model:list同步
		const newList = currentList.value.map(item => {
			const { index, y, animation, ...rest } = item
			return rest
		})
		emits('update:list', newList)
	}
	function updateActive(index: number) {
		const item = currentList.value[index]
		if (!item.removable && item.active) {
			uni.showToast({
				title: '此模块为必选模块，不可移除',
				icon: 'none'
			})
			return
		}
		item.active = !item.active
		// 这里可根据需要emit事件通知父组件
		emits('update:active', { modelName: item.modelName, active: item.active })
	}
</script>

<style lang='scss' scoped>
@import "./1px.scss";
.drag-sort {
  width: 100%;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.drag-sort-item {
  width: 100%;
}
.module-item {
  display: flex;
  align-items: center;
  background-color: #FFFFFF;
  border-radius: 8px;
  padding: 16px;
  box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05);
  transition: transform 0.2s ease, box-shadow 0.2s ease;
  &.active {
    border-left: 4px solid #5ac725;
  }
  .handle {
    margin-right: 12px;
    display: flex;
    align-items: center;
    cursor: grab;
  }
  .content {
    flex: 1;
    font-size: 16px;
    color: #333;
  }
  .action {
    padding: 4px;
  }
  &:active {
    cursor: grabbing;
    transform: scale(1.02);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  }
}
.touch {
  height: 100%;
  width: 50px;
}
.ico_drag {
  display: inline-block;
  width: 24px;
  height: 12px;
  background: url() 0 0 no-repeat;
  background-size: 100% auto;
}
.drag-sort-item.active {
  z-index: 99;
}
</style>
